﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;

namespace XML
{
    public partial class frmXuLy : Form
    {
        List<string> lstMSSV;
        XmlDocument doc = new XmlDocument();

        public frmXuLy()
        {
            InitializeComponent();
            lstMSSV = new List<string>();
        }

        #region -----> Event <-----

        //-----> Load Form
        private void frmXuLy_Load(object sender, EventArgs e)
        {
            bool success = ValidateXml("QLSV.xml", "QLSV.xsd");
            if (!success)
            {
                MessageBox.Show("File XMl của bạn không hợp lệ! \nHãy kiểm tra lại.", "Thông báo", MessageBoxButtons.OK);
            }
            else
            {
                MessageBox.Show("File XMl của bạn hợp lệ! \nBấm Ok để tiếp tục", "Thông báo", MessageBoxButtons.OK);
                ShowDataSV();
            }
        }

        //-----> Add record
        private void btnThem_Click(object sender, EventArgs e)
        {
            if (CheckAll(true))
            {
                Add();
                ShowDataSV();
            }   
        }

        //-----> Delete record
        private void btnXoa_Click(object sender, EventArgs e)
        {
            Delete();
            ShowDataSV();
        }

        //-----> Update record
        private void btnSua_Click(object sender, EventArgs e)
        {
            if (CheckAll(false))
            {
                Update();
                ShowDataSV();
            }  
        }

        //-----> Clear
        private void btnXoaTrang_Click(object sender, EventArgs e)
        {
            txtMSSV.Text = "";
            txtHoTen.Text = "";
            cbLop.SelectedIndex = 0;
            dtGridMH.Rows.Clear();

            txtMSSV.Enabled = true;

            btnThem.Enabled = true;
            btnXoa.Enabled = false;
            btnSua.Enabled = false;
        }

        //-----> Exit Program
        private void btnThoat_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //-----> Export file HTML
        private void btnHTML_Click(object sender, EventArgs e)
        {
            XslTransform transform = new XslTransform();

            transform.Load("QLSVHTML.xslt");

            saveFileDialog1.Filter = "HTML file(*.html)|*.html";
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                transform.Transform("QLSV.xml", saveFileDialog1.FileName, null);

                MessageBox.Show("Xuất ra file HTML thành công", "Thông báo", MessageBoxButtons.OK);

                if (checkOpen.Checked)
                {
                    FileInfo file = new FileInfo(saveFileDialog1.FileName);
                    if (file.Exists)
                    {
                        Process.Start(saveFileDialog1.FileName);
                    }
                }
            } 
        }

        //-----> Export file CSV
        private void btnCSV_Click(object sender, EventArgs e)
        {
            XslTransform transform = new XslTransform();

            transform.Load("QLSVCSV.xslt");

            saveFileDialog1.Filter = "CSV file(*.csv)|*.csv";
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                transform.Transform("QLSV.xml", saveFileDialog1.FileName, null);

                MessageBox.Show("Xuất ra file CSV thành công", "Thông báo", MessageBoxButtons.OK);

                if (checkOpen.Checked)
                {
                    FileInfo file = new FileInfo(saveFileDialog1.FileName);
                    if (file.Exists)
                    {
                        Process.Start(saveFileDialog1.FileName);
                    }
                }
            }
        }

        //-----> Export file JSON
        private void btnJSon_Click(object sender, EventArgs e)
        {
            saveFileDialog1.Filter = "JSON file(*.json)|*.json";
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                XPathDocument doc = new XPathDocument("QLSV.xml");
                XslCompiledTransform transform = new XslCompiledTransform(true);
                transform.Load("QLSVJSON.xslt");
                XmlTextWriter writer = new XmlTextWriter(saveFileDialog1.FileName, null);
                transform.Transform(doc, null, writer);

                MessageBox.Show("Xuất ra file JSON thành công", "Thông báo", MessageBoxButtons.OK);

                if (checkOpen.Checked)
                {
                    FileInfo file = new FileInfo(saveFileDialog1.FileName);
                    if (file.Exists)
                    {
                        Process.Start(saveFileDialog1.FileName);
                    }
                }
            }
        }

        //-----> Tra Cứu 
        private void btnTraCuu_Click(object sender, EventArgs e)
        {
            frmTraCuu trCuu = new frmTraCuu();
            trCuu.ShowDialog();
        }

        //-----> DataGridView select change
        private void dtGridSV_SelectionChanged(object sender, EventArgs e)
        {
            DataGridViewCell cell = null;
            foreach (DataGridViewCell selectedCell in dtGridSV.SelectedCells)
            {
                cell = selectedCell;
                break;
            }
            if (cell != null)
            {
                DataGridViewRow row = cell.OwningRow;
                if (row.Cells["MSSV"].Value != null)
                {
                    txtMSSV.Text = row.Cells["MSSV"].Value.ToString();
                    txtHoTen.Text = row.Cells["HoTen"].Value.ToString();
                    cbLop.Text = row.Cells["Lop"].Value.ToString();
                    ShowDataMH(txtMSSV.Text);

                    txtMSSV.Enabled = true;

                    btnThem.Enabled = true;
                    btnXoa.Enabled = true;
                    btnSua.Enabled = true;
                }
            }
        }

        #endregion

        #region -----> Methods <-----

        //-----> Hàm kiêm tra file XML xem có hợp cấu trúc file schema không
        private bool ValidateXml(string xmlFilename, string schemaFilename)
        {
            // Tạo Validator
            XmlTextReader r = new XmlTextReader(xmlFilename);
            XmlValidatingReader validator = new XmlValidatingReader(r);
            validator.ValidationType = ValidationType.Schema;

            // Nạp Schema vào Validator
            XmlSchemaCollection schemas = new XmlSchemaCollection();
            schemas.Add(null, schemaFilename);
            validator.Schemas.Add(schemas);

            bool failed = false;

            try
            {
                doc.Load(validator);
            }
            catch (XmlSchemaException err)
            {
                failed = true;
            }
            finally
            {
                validator.Close();
            }

            return !failed;
        }

        //-----> Hàm hiển thị dữ liệu sinh viên
        private void ShowDataSV()
        {
            lstMSSV.Clear();
            dtGridSV.Rows.Clear();
            int i = 0;
            foreach (XmlNode node in doc.ChildNodes[1].ChildNodes)
            {
                dtGridSV.Rows.Add();
                lstMSSV.Add(node.ChildNodes[0].InnerText);
                dtGridSV.Rows[i].Cells["MSSV"].Value = node.ChildNodes[0].InnerText;
                dtGridSV.Rows[i].Cells["HoTen"].Value = node.ChildNodes[1].InnerText;
                dtGridSV.Rows[i].Cells["Lop"].Value = node.ChildNodes[2].InnerText;
                i++;
            }
            dtGridSV.Sort(dtGridSV.Columns["MSSV"], ListSortDirection.Ascending);
            for (int j = 0; j < dtGridSV.Rows.Count - 1; j++)
            {
                dtGridSV.Rows[j].Cells["STT"].Value = (j + 1).ToString();
            }
        }

        //-----> Hàm hiển thị dữ liệu môn học
        private void ShowDataMH(string mssv)
        {
            dtGridMH.Rows.Clear();
            XmlNode node = doc.SelectSingleNode("/ListStudent/Student[MSSV = " + mssv + "]");

            foreach (XmlNode Node in node.ChildNodes)
            {
                if (Node.Name == "ListSubject")
                {
                    int i = 0;
                    foreach (XmlNode subNode in Node.ChildNodes)
                    {
                        dtGridMH.Rows.Add();
                        foreach (XmlNode sub in subNode.ChildNodes)
                        {
                            if (sub.Name == "NameSub")
                            {
                                dtGridMH.Rows[i].Cells["TenMon"].Value = sub.InnerText;
                            }

                            if (sub.Name == "SoTC")
                            {
                                dtGridMH.Rows[i].Cells["SoTC"].Value = sub.InnerText;
                            }

                            if (sub.Name == "Diem")
                            {
                                dtGridMH.Rows[i].Cells["Diem"].Value = sub.InnerText;
                            }
                        }
                        i++;
                    }
                }
            }
        }

        //-----> Hàm thêm thông tin sinh viên
        private void Add()
        {
            XmlElement student = doc.CreateElement("Student");
            XmlElement mssv = doc.CreateElement("MSSV");
            XmlElement hoten = doc.CreateElement("HoTen");
            XmlElement lop = doc.CreateElement("Lop");
            XmlElement lstSub = doc.CreateElement("ListSubject");

            mssv.InnerText = txtMSSV.Text;
            hoten.InnerText = txtHoTen.Text;
            lop.InnerText = cbLop.SelectedItem.ToString();

            for (int i = 0; i < dtGridMH.Rows.Count - 1; i++)
            {
                XmlElement namesub = doc.CreateElement("NameSub");
                XmlElement sotc = doc.CreateElement("SoTC");
                XmlElement diem = doc.CreateElement("Diem");

                namesub.InnerText = dtGridMH.Rows[i].Cells["TenMon"].Value.ToString();
                sotc.InnerText = dtGridMH.Rows[i].Cells["SoTC"].Value.ToString();
                diem.InnerText = dtGridMH.Rows[i].Cells["Diem"].Value.ToString();

                XmlElement sub = doc.CreateElement("Subject");
                sub.AppendChild(namesub);
                sub.AppendChild(sotc);
                sub.AppendChild(diem);

                lstSub.AppendChild(sub);
            }

            student.AppendChild(mssv);
            student.AppendChild(hoten);
            student.AppendChild(lop);
            student.AppendChild(lstSub);

            doc.DocumentElement.AppendChild(student);
            doc.Save(Application.StartupPath + "\\QLSV.xml");
            MessageBox.Show("Thêm thông tin sinh viên thành công", "Thông báo", MessageBoxButtons.OK);
        }

        //-----> Hàm xóa thông tin sinh viên
        private void Delete()
        {
            XmlNode node = doc.SelectSingleNode("/ListStudent/Student[MSSV = " + txtMSSV.Text + "]");

            if (node != null)
            {
                doc.DocumentElement.RemoveChild(node);
            }

            doc.Save(Application.StartupPath + "\\QLSV.xml");
            MessageBox.Show("Xóa thông tin sinh viên thành công", "Thông báo", MessageBoxButtons.OK);
        }

        //-----> Hàm cập nhật thông tin sinh viên
        private void Update()
        {
            XmlNode node = doc.SelectSingleNode("/ListStudent/Student[MSSV = " + txtMSSV.Text + "]");

            if (node != null)
            {
                node.ChildNodes[1].InnerText = txtHoTen.Text;
                node.ChildNodes[2].InnerText = cbLop.SelectedItem.ToString();
                int i = 0;
                foreach (XmlNode lstSub in node.ChildNodes[3].ChildNodes)
                {
                    lstSub.ChildNodes[0].InnerText = dtGridMH.Rows[i].Cells["TenMon"].Value.ToString();
                    lstSub.ChildNodes[1].InnerText = dtGridMH.Rows[i].Cells["SoTC"].Value.ToString();
                    lstSub.ChildNodes[2].InnerText = dtGridMH.Rows[i].Cells["Diem"].Value.ToString();
                    i++;
                }

                doc.Save(Application.StartupPath + "\\QLSV.xml");
                MessageBox.Show("Cập nhật thông tin sinh viên thành công", "Thông báo", MessageBoxButtons.OK);
            }
        }

        //-----> Hàm kiểm tra tất cả
        private bool CheckAll(bool insert)
        {
            if (!insert)
            {
                if (CheckHoTen())
                {
                    if (CheckMonHoc())
                    {
                        return true;
                    }
                }
            }
            else
            {
                if (CheckMSSV())
                {
                    if (CheckHoTen())
                    {
                        if (CheckMonHoc())
                        {
                            return true;
                        }
                    }
                }
            }
            
            return false;
        }

        //-----> Hàm kiểm tra MSSV
        private bool CheckMSSV()
        {
            if (txtMSSV.Text.Length == 0)
            {
                MessageBox.Show("Không được bỏ trống MSSV", "Thông báo", MessageBoxButtons.OK);
                return false;
            }
            else
            {
                if (txtMSSV.Text.Length > 8)
                {
                    MessageBox.Show("MSSV không quá 8 số", "Thông Báo", MessageBoxButtons.OK);
                    return false;
                }
                else
                {
                    if (txtMSSV.Text.Length < 8)
                    {
                        MessageBox.Show("MSSV phải đủ 8 số", "Thông Báo", MessageBoxButtons.OK);
                        return false;
                    }
                    else
                    {
                        if (!checkDigit(txtMSSV.Text))
                        {
                            MessageBox.Show("MSSV chỉ gồm số không có kí tự", "Thông báo", MessageBoxButtons.OK);
                            return false;
                        }
                        else
                        {
                            for (int i = 0; i < lstMSSV.Count; i++)
                            {
                                if (txtMSSV.Text == lstMSSV[i] && txtMSSV.Enabled == true)
                                {
                                    MessageBox.Show("MSSV này đã tồn tài, hãy đổi MSSV khác", "Thông báo", MessageBoxButtons.OK);
                                    return false;
                                }
                            }
                        }
                    }
                }
            }

            return true;
        }

        //-----> Hàm kiểm tra Họ Tên
        private bool CheckHoTen()
        {
            bool check = true;

            if (txtHoTen.Text.Length == 0)
            {
                check = false;
                MessageBox.Show("Không được bỏ trống Họ tên", "Thông báo", MessageBoxButtons.OK);
            }

            return check;
        }

        //-----> Hàm kiểm trả Môn học
        private bool CheckMonHoc()
        {
            if (dtGridMH.Rows.Count == 1)
            {
                MessageBox.Show("Danh sách môn học trống", "Thông báo", MessageBoxButtons.OK);
                return false;
            }
            else
            {
                for (int i = 0; i < dtGridMH.Rows.Count - 1; i++)
                {
                    if(dtGridMH.Rows[i].Cells["TenMon"].Value == null)
                    {
                        MessageBox.Show("Không được bỏ trống môn học", "Thông báo", MessageBoxButtons.OK);
                        return false;
                    }

                    if (dtGridMH.Rows[i].Cells["SoTC"].Value == null)
                    {
                        MessageBox.Show("Không được bỏ trống số tín chỉ", "Thông báo", MessageBoxButtons.OK);
                        return false;
                    }
                    else
                    {
                        string soTC = dtGridMH.Rows[i].Cells["SoTC"].Value.ToString();
                        if (!CheckSoTC(soTC))
                        {
                            return false;
                        }
                    }

                    if (dtGridMH.Rows[i].Cells["Diem"].Value == null)
                    {
                        MessageBox.Show("Không được bỏ trống số điểm", "Thông báo", MessageBoxButtons.OK);
                        return false;
                    }
                    else
                    {
                        string Diem = dtGridMH.Rows[i].Cells["Diem"].Value.ToString();
                        if (!CheckDiem(Diem))
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }

        //-----> Hàm kiểm tra số tín chỉ
        private bool CheckSoTC(string soTC)
        {
            if (soTC.Length == 1 && (soTC == "1" || soTC == "2" || soTC == "3" || soTC == "4" || soTC == "5"))
            {
                return true;
            }
            else
            {
                MessageBox.Show("Số tín chỉ từ 1 đến 5 và là số nguyên", "Thông báo", MessageBoxButtons.OK);
                return false;
            }

            return true;
        }

        //-----> Hàm kiểm tra điểm
        private bool CheckDiem(string SoDiem)
        {
            try
            {
                double diem = Convert.ToDouble(SoDiem);
                if (0 <= diem && diem <= 10)
                {
                    return true;
                }
                else
                {
                    MessageBox.Show("Số điểm từ 0 đến 10", "Thông báo", MessageBoxButtons.OK);
                    return false;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Điểm là số thực từ 0 đến 10 không nhập kí tự", "Thông báo", MessageBoxButtons.OK);
                return false;
            }

            return true;
        }

        //-----> Hàm kiểm tra chuỗi số
        private bool checkDigit(string s)
        {
            for (int i = 0; i < s.Length; i++)
            {
                if (char.IsDigit(s[i]) != true)
                    return false;
            }
            return true;
        }

        #endregion   
    }
}
